﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace NetWork
{
    #region 简单的混合锁
    /// <summary>
    /// 一个简单的混合线程同步锁，采用了基元用户加基元内核同步构造实现
    /// </summary>
    public sealed class SimpleHybirdLock : IDisposable
    {
        /// <summary>
        /// 一个简单的混合线程同步锁，采用了基元用户加基元内核同步构造实现
        /// </summary>
        public SimpleHybirdLock()
        {
        }
        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用
        void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                }
                m_waiterLock.Close();
                disposedValue = true;
            }
        }
        // 添加此代码以正确实现可处置模式。
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }
        #endregion
        /// <summary>
        /// 基元用户模式构造同步锁
        /// </summary>
        private int m_waiters = 0;
        /// <summary>
        /// 基元内核模式构造同步锁
        /// </summary>
        private AutoResetEvent m_waiterLock = new AutoResetEvent(false);
        /// <summary>
        /// 获取锁
        /// </summary>
        public void Enter()
        {
            if (Interlocked.Increment(ref m_waiters) == 1) return;//用户锁可以使用的时候，直接返回，第一次调用时发生
            //当发生锁竞争时，使用内核同步构造锁
            m_waiterLock.WaitOne();
        }
        /// <summary>
        /// 离开锁
        /// </summary>
        public void Leave()
        {
            if (Interlocked.Decrement(ref m_waiters) == 0) return;//没有可用的锁的时候
            m_waiterLock.Set();
        }
        /// <summary>
        /// 获取当前锁是否在等待当中
        /// </summary>
        public bool IsWaitting
        {
            get
            {
                return (m_waiters != 0);
            }
        }
    }
    #endregion
    #region 乐观并发模型的协调类
    /// <summary>
    /// 一个用于高性能，乐观并发模型控制操作的类，允许一个方法(隔离方法)的安全单次执行
    /// </summary>
    public sealed class HslAsyncCoordinator
    {
        /// <summary>
        /// 实例化一个对象，需要传入隔离执行的方法
        /// </summary>
        /// <param name="operater">隔离执行的方法</param>
        public HslAsyncCoordinator(Action operater)
        {
            action = operater;
        }
        /// <summary>
        /// 操作状态，0是未操作，1是操作中
        /// </summary>
        private int OperaterStatus = 0;
        /// <summary>
        /// 需要操作的次数
        /// </summary>
        private long Target = 0;
        /// <summary>
        /// 启动线程池执行隔离方法
        /// </summary>
        public void StartOperaterInfomation()
        {
            Interlocked.Increment(ref Target);
            if (Interlocked.CompareExchange(ref OperaterStatus, 1, 0) == 0)
            {
                //启动保存
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolOperater), null);
            }
        }
        private Action action = null;
        private void ThreadPoolOperater(object obj)
        {
            long currentVal = Target, startVal;
            long desiredVal = 0;
            do
            {
                startVal = currentVal;//设置值
                // 以下为业务逻辑，允许实现非常复杂的设置
                action.Invoke();
                // 需要清零值的时候必须用下面的原子操作
                currentVal = Interlocked.CompareExchange(ref Target, desiredVal, startVal);
            }
            while (startVal != currentVal);// 更改失败就强制更新
            // 退出保存状态
            Interlocked.Exchange(ref OperaterStatus, 0);
            // 最终状态确认
            if (Target != desiredVal) StartOperaterInfomation();
        }
    }
    #endregion
}
